#ifndef _HEAD__C_H
#define _HEAD__C_H

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <signal.h>
#include <math.h>
#include <time.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <ctype.h>
#include <crypt.h>
#include <pwd.h>
#include <grp.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <mysql/mysql.h>
#include <syslog.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/select.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/epoll.h>
#include <sys/sendfile.h>

// 检查命令行参数数量是否符合预期
#define ARGS_CHECK(argc,expected) \
    do { \
        if((argc)!=(expected)){ \
            fprintf(stderr, "args num error!\n"); \
            exit(1); \
        } \
    } while (0)

// 检查返回值是否是错误标记，若是则打印msg和错误信息
#define ERROR_CHECK(ret,error_flag,msg) \
    do { \
        if((ret)==(error_flag)){ \
            perror(msg); \
            exit(1); \
        } \
    } while(0)

#define THREAD_ERROR_CHECK(ret,msg) \
    do { \
        if(ret!=0){ \
            fprintf(stderr,"%s:%s\n",msg,strerror(ret)); \
        } \
    } while(0)


#define INFOLEN (sizeof(user_info))
//客户端发给服务器的结构体
typedef struct {
    char path[1024];
    int path_tail;

    char username[256];
    char password[1024];

    int command_num;
    char command_str_goto[1024];
    char command_str_return[1024];

    int flag;
    char token[2048];
}path_t, user_info;

typedef struct train_s {
    int len;
    char buf[1024];
}train_t;

typedef struct user{
    char *username;
    char *password;
}user_t;

//发送命令参数
void sendCommand(int net_fd, char *path);
//读取配置文件信息
int getparameter(char *key, char *value);

int addEpoll(int epoll_fd, int fd);
int client_download(int net_fd);
//int client_upload(int net_fd, char *path, char *file_name);
int client_upload(int net_fd, user_info info);
void md5(char *file_name, char *md5_num);
//分析处理标准输入的命令
char *splitCommand(char *command_str, int *command_number);

void changeVirtualDir(path_t *path, char *command_path);

//发送info结构体
void sendInfoStruct(int net_fd, user_info *info);
void recvInfoStruct(int net_fd, user_info *info);

int userLoginClient(int net_fd, user_info *info, char *password);
int userRegisterClient(int net_fd, user_info *info, char *password); 

//客户端路径处理
void changePath(user_info *info);
#endif
